﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace P2PTransmit.ViewModal
{
    public class AsyncObservableCollection<T>:ObservableCollection<T>
    {
        readonly SynchronizationContext _context;
        public AsyncObservableCollection() : base()
        {
            _context = SynchronizationContext.Current;            
        }

        #region Insert
        protected override void InsertItem(Int32 index, T item)
        {
            if(_context != SynchronizationContext.Current)
            {
                _context.Post(InsertItem, item);
            }
            else
            {
                base.InsertItem(index, item);
            }           
        }

        protected void InsertItem(object obj)
        {
            base.InsertItem(base.Count, (T)obj);
        }
        #endregion

        #region Remove
        protected override void RemoveItem(Int32 index)
        {
            if (_context != SynchronizationContext.Current)
            {
                _context.Post(OnRemoveItem, index);
            }
            else
            {
                base.RemoveItem(index);
            }
            
        }
        protected void OnRemoveItem(object obj)
        {
            base.RemoveItem((int)obj);
        }
        #endregion

        #region Move
        volatile int _oldIndex;
        protected override void MoveItem(Int32 oldIndex, Int32 newIndex)
        {
            if(_context != SynchronizationContext.Current)
            {
                _oldIndex = oldIndex;
                _context.Post(Move, newIndex);
            }
            else
            {
                base.MoveItem(oldIndex, newIndex);
            }
        }

        protected void Move(object newIndex)
        {
            base.MoveItem(_oldIndex, (int)newIndex);
        }
        #endregion

        #region SetItem
        protected override void SetItem(Int32 index, T item)
        {
            if(_context != SynchronizationContext.Current)
            {
                _context.Post(SetItem, item);
            }
            else
            {
                base.SetItem(index, item);
            }            
        }

        protected void SetItem(object o)
        {
            base.SetItem(base.Count, (T)o);
        }
        #endregion

        #region Clear
        protected override void ClearItems()
        {
            if (_context != SynchronizationContext.Current)
            {
                _context.Post(ClearItem, null);
            }
            else
            {
                base.ClearItems();
            }
        }
        protected void ClearItem(object o)
        {
            base.ClearItems();
        }
        #endregion
    }
}
